package com.wonder.app.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vtuzx.core.utils.VtuzxUtil;
import com.wonder.app.domain.*;
import com.wonder.app.mapper.*;
import com.wonder.app.service.*;
import com.wonder.common.utils.DateUtils;
import com.wonder.constant.BillType;
import com.wonder.constant.IXqcConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import org.web3j.abi.datatypes.Int;

import java.util.*;

@Service
public class StkTransferAppServiceImpl extends ServiceImpl<StkTransferAppDao, StkTransferApp> implements StkTransferAppService {
    /** 日志 */
    private static final Logger _logger = LoggerFactory.getLogger(StkTransferAppServiceImpl.class);

    @Autowired
    private SyncKingdeeOrderService syncKingdeeOrderService;

    @Autowired
    private StkTransferAppService stkTransferAppService;

    @Autowired
    private StkTransferAppDao stkTransferAppDao;

    @Autowired
    private StkTransferAppDetailService stkTransferAppDetailService;

    @Autowired
    private StkTransferDetailDao stkTransferDetailDao;

    @Autowired
    private StkTransferDetailService stkTransferDetailService;

    @Autowired
    private StkTransferAppDetailDao stkTransferAppDetailDao;

    @Autowired
    private StkTransferService stkTransferService;

    @Autowired
    private TrayDao trayDao;

    @Autowired
    private TrayService trayService;


    /**
     * 金蝶审核调拨申请单
     * @param map
     * @return
     */
    @Override
    public boolean audit(JSONObject map) {
        _logger.info("审核调拨申请单"+ map.toString());
        JSONArray transferList = map.getJSONArray("TransferList");
        JSONObject transferObj = (JSONObject) transferList.get(0);
        JSONArray head = transferObj.getJSONArray("model");//单据头数据
        JSONArray detailList = transferObj.getJSONArray("detail");//单据体数据、
        List<StkTransferApp> stkTransferAppList = new ArrayList<>();//添加到单据头的数据
        List<StkTransferAppDetaill> stkTransferAppDetaillList = new ArrayList<>();//添加到单据体的数据
        List<Long> fidList = new ArrayList<>();//单据头需要删除的fid集合
        List<Long> entryIdList = new ArrayList<>();//单据体需要删除的entryid集合
        for (Object obj : head) {
            JSONObject jsonObject = (JSONObject) obj;
            //将json直接转成实体类
            StkTransferApp stkTransferApp = jsonObject.toBean(StkTransferApp.class);
            stkTransferApp.setSTATUS("save");
            stkTransferApp.setCLOSTSTATUS(false);
            Long fid = stkTransferApp.getFID();
            if (!fidList.contains(fid)){
                fidList.add(fid);
            }

            stkTransferAppList.add(stkTransferApp);
        }
        //单据体数据
        for (Object obj : detailList) {
            JSONObject jsonObject = (JSONObject) obj;
            //将json直接转成实体类
            StkTransferAppDetaill stkTransferAppDetaill = jsonObject.toBean(StkTransferAppDetaill.class);
            stkTransferAppDetaill.setCLOSTSTATUS(false);
            Long entryId = stkTransferAppDetaill.getFENTRYID();
            if (!entryIdList.contains(entryId)){
                entryIdList.add(entryId);
            }
            stkTransferAppDetaillList.add(stkTransferAppDetaill);
        }


        //查询有没有需要删除的单据
        List<StkTransferApp> applyDelete =  stkTransferAppDao.selectList(new LambdaQueryWrapper<StkTransferApp>()
                .in(StkTransferApp::getFID,fidList));
        if (null != applyDelete || applyDelete.size() > 0){
            stkTransferAppDao.delete(new LambdaQueryWrapper<StkTransferApp>()
                    .in(StkTransferApp::getFID,fidList));

        }
        List<StkTransferAppDetaill> receivedetails =  stkTransferAppDetailDao.selectList(new LambdaQueryWrapper<StkTransferAppDetaill>()
                .in(StkTransferAppDetaill::getFENTRYID,entryIdList));
        if (null != receivedetails || receivedetails.size() > 0){
            stkTransferAppDetailDao.delete(new LambdaQueryWrapper<StkTransferAppDetaill>()
                    .in(StkTransferAppDetaill::getFENTRYID,entryIdList));

        }
        //向数据库添加数据
        boolean resHead = stkTransferAppService.saveOrUpdateBatch(stkTransferAppList);
        boolean res = stkTransferAppDetailService.saveOrUpdateBatch(stkTransferAppDetaillList);
        return res && resHead;
    }

    /**
     * 调拨申请单列表手机端(显示调拨申请详情信息)
     * @param map
     * @return
     */
    @Override
    public Map<String, Object> getStkTransferAppList(Map<String, Object> map) {
        int pageIndex = VtuzxUtil.getInt(map,"pageIndex");
        int pageSize = VtuzxUtil.getInt(map,"pageSize");
        String billNo = VtuzxUtil.getString(map,"billNo");//订单号
        //直接查询明细展示明细信息
        List<StkTransferApp> dataList = stkTransferAppDao.getStkTransferAppList(pageSize,pageIndex * pageSize,billNo);
        Map<String,Object> data = new HashMap<>();
        data.put("dataList",dataList);
        return data;
    }

    /**
     * 调拨申请单详情(手机端)
     * @param map
     * @return
     */
    @Override
    public Map<String, Object> getStkTransferAppDetail(Long user_id, Map<String, Object> map) {
        Long detailId = VtuzxUtil.getLong(map,"detailId");//调拨申请单据头id
//        StkTransferAppDetaill stkTransferAppDetaill = stkTransferAppDetailDao.selectById(detailId);
        StkTransferApp stkTransferApp = stkTransferAppDao.selectOne(new LambdaQueryWrapper<StkTransferApp>()
                .eq(StkTransferApp::getFID,detailId));

//        if (null == stkTransferApp){
//            throw new RuntimeException("单号错误请重试");
//        }
//        Long fid = stkTransferApp.getFID();
//        //通过fid查询详情数据
//        List<StkTransferAppDetaill> stkTransferAppDetaillList = stkTransferAppDetailDao.selectList(new LambdaQueryWrapper<StkTransferAppDetaill>()
//                .eq(StkTransferAppDetaill::getFID,fid));

        //根据调拨申请详情Id查询调拨单详情临时数据
        List<StkTransferDetail> transferDetailList = stkTransferDetailDao.selectList(new LambdaQueryWrapper<StkTransferDetail>()
                .eq(StkTransferDetail::getTEMP, true)
                .eq(StkTransferDetail::getUSERID, user_id)
                .eq(StkTransferDetail::getTransferAppId, detailId));
        Map<String,Object> data = new HashMap<>();
        data.put("data",stkTransferApp);
//        data.put("detail",stkTransferAppDetaill);
        data.put("dataList",transferDetailList);
        return data;
    }

    /**
     * 审核调拨申请单
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public Boolean auditStkTransferApp(Long user_id,String userName,Map<String, Object> map) throws Exception {
        //先保存调拨申请单的仓位信息，在生成调拨单
        String stockNo = VtuzxUtil.getString(map,"stockNo");//调入仓库编码
        String locationNo = VtuzxUtil.getString(map,"locationNo");//调入仓位编码
//        Map<String,Object> detail = VtuzxUtil.getObject(map,"detail");//调拨申请详情信息
        Map<String,Object> header = VtuzxUtil.getObject(map,"header");//调拨申请单据头
        //生成调拨单的外层表信息，修改调拨内层表信息
        Long appFId = VtuzxUtil.getLong(header,"fid");//调拨申请单据头fid
        List<StkTransferDetail> transferDetailList = stkTransferDetailDao.selectList(new LambdaQueryWrapper<StkTransferDetail>()
                .eq(StkTransferDetail::getTEMP, true)
                .eq(StkTransferDetail::getTransferAppId, appFId)
                .eq(StkTransferDetail::getUSERID, user_id));

        StkTransfer stkTransfer = new StkTransfer();//调拨单单据头
        String billNo = IXqcConst.createBillNo(BillType.DBRK);
        stkTransfer.setFBillNo(billNo);
        stkTransfer.setCreateTime(new Date());
        stkTransfer.setFCREATEUSER(userName);
        Date date = DateUtils.adjustDateTransfer(new Date());
        stkTransfer.setFDATE(date);

        List<String> trayNoList = new ArrayList<>();
        for (StkTransferDetail stkTransferDetail : transferDetailList){
            stkTransferDetail.setTEMP(false);
            stkTransferDetail.setFBILLNO(billNo);
            stkTransferDetail.setFDestStockId(stockNo);//调入仓库编码
            stkTransferDetail.setFDestStockLocId(locationNo);//调入仓位编码

            String trayno = stkTransferDetail.getTRAYNO();
            if (!trayNoList.contains(trayno)){
                trayNoList.add(trayno);
            }
        }
        //调拨单传金蝶
        try {
            syncKingdeeOrderService.syncTransfer(user_id,stkTransfer,transferDetailList);
        } catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }
        boolean res = stkTransferService.save(stkTransfer);
        boolean detailRes = stkTransferDetailService.saveOrUpdateBatch(transferDetailList);
        //调拨成功后需要修改托盘信息仓库和仓位

        if (!VtuzxUtil.isEmpty(trayNoList)){
            boolean update = trayService.update(null, Wrappers.<Tray>lambdaUpdate()
                .in(Tray::getFBILLNO, trayNoList)
                .set(Tray::getLOCATIONNO,locationNo)
                .set(Tray::getSTOCKNO, stockNo)
                .set(Tray::getISPACKAGE,false));
        }



        return res;
    }

    /**
     * 修改调拨申请详情数据
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public Boolean updateStkTransferAppDetail(Map<String, Object> map) throws Exception {
        Map<String,Object> currentData = VtuzxUtil.getObject(map,"currentData");//需要修改的调拨详情数据
        Map<String,Object> trayData = VtuzxUtil.getObject(map,"trayData");//托盘信息
        //修改数量,和添加托盘信息

        Integer detailId = VtuzxUtil.getInt(currentData,"id");//调拨详情id
        Double fqty = VtuzxUtil.getDouble(trayData,"fqty");//托盘数量
        String locationNo = VtuzxUtil.getString(trayData,"locationno");
        String trayNo = VtuzxUtil.getString(trayData,"fbillno");
        StkTransferAppDetaill stkTransferAppDetaill = stkTransferAppDetailDao.selectById(detailId);
        stkTransferAppDetaill.setFQTY(fqty);
        stkTransferAppDetaill.setFLOCATIONO(locationNo);//调出仓位
        stkTransferAppDetaill.setTRAYNO(trayNo);
        boolean b = stkTransferAppDetailService.updateById(stkTransferAppDetaill);

        return b;
    }

    /**
     * 调拨申请关闭
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public boolean applyClose(JSONObject map) throws Exception {
        _logger.info("调拨申请关闭:"+map.toString());
        JSONArray detailList = map.getJSONArray("applyCloseList");
//        JSONObject applyObj = (JSONObject) applyJson.get(0);
//        JSONArray detailList = applyObj.getJSONArray("applyCloseList");//关闭数据
        boolean first= true;
        boolean resDetail = false;
        for (Object obj : detailList) {
            JSONObject item = (JSONObject) obj;
            String applyBillNo = item.getStr("FBILLNO");//单据编号
            int FID  = item.getInt("FID");//单据内码
            String FCLOSESTATUS = item.getStr("FCLOSESTATUS");//单据头关闭状态A正常B关闭
            String FBUSINESSCLOSED = item.getStr("FBUSINESSCLOSED");//业务关闭状态A正常B业务关闭
            String FBUSINESSEND= item.getStr("FBUSINESSEND");//业务终止
            int FENTRYID = item.getInt("FENTRYID");//单据体内码
            if (first && FCLOSESTATUS.equals("B")){//第一行整单关闭的话单据头单据体都直接修改
                StkTransferApp stkTransferApp = stkTransferAppDao.selectOne(new LambdaQueryWrapper<StkTransferApp>()
                        .eq(StkTransferApp::getFBILLNO,applyBillNo));
                if (null == stkTransferApp){
                    throw new RuntimeException(String.format("未查询到数据单号%s", applyBillNo));
                }
                stkTransferApp.setCLOSTSTATUS(true);
                List<StkTransferAppDetaill> stkTransferAppDetaillList = stkTransferAppDetailDao.selectList(new LambdaQueryWrapper<StkTransferAppDetaill>()
                        .eq(StkTransferAppDetaill::getFID,FID));
                for (StkTransferAppDetaill stkApplyDetail : stkTransferAppDetaillList){
                    stkApplyDetail.setCLOSTSTATUS(true);
                }
                boolean reshead = stkTransferAppService.saveOrUpdate(stkTransferApp);
                resDetail = stkTransferAppDetailService.saveOrUpdateBatch(stkTransferAppDetaillList);
            }else{//每行单据状态关闭都改
                if (FBUSINESSCLOSED.equals("B") || FBUSINESSEND.equals("B")) {
                    StkTransferAppDetaill stkTransferAppDetaill = stkTransferAppDetailDao.selectOne(new LambdaQueryWrapper<StkTransferAppDetaill>()
                            .eq(StkTransferAppDetaill::getFENTRYID,FENTRYID));
                    if (null == stkTransferAppDetaill){
                        throw new RuntimeException(String.format("未查询到数据单号%s", applyBillNo));
                    }
                    stkTransferAppDetaill.setCLOSTSTATUS(true);
                    resDetail = stkTransferAppDetailService.saveOrUpdate(stkTransferAppDetaill);
                }

            }
            first = false;
        }
        return resDetail;
    }

    /**
     * 调拨申请反审核
     * @param map
     * @return
     * @throws Exception
     */
    public boolean unAudit(JSONObject map) throws Exception {
        _logger.info("调拨申请反审核:"+map.toString());
        JSONArray detailList = map.getJSONArray("applyList");
        List<Long> billNoList = detailList.toList(long.class);
        //批量删除多行数据
        boolean remove = stkTransferAppService.remove(new LambdaQueryWrapper<StkTransferApp>()
                .in(StkTransferApp::getFID,billNoList));
        boolean detailRes = stkTransferAppDetailService.remove(new LambdaQueryWrapper<StkTransferAppDetaill>()
                .in(StkTransferAppDetaill::getFID,billNoList));
        return remove && detailRes;
    }

    /**
     * 审核调拨申请单包材
     * @param user_id
     * @param userName
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public Boolean auditStkTransferAppBaoCai(Long user_id, String userName, Map<String, Object> map) throws Exception {
        //先保存调拨申请单的仓位信息，在生成调拨单
        String stockNo = VtuzxUtil.getString(map,"stockNo");//调入仓库编码
        String locationNo = VtuzxUtil.getString(map,"locationNo");//调入仓位编码
        Map<String,Object> detail = VtuzxUtil.getObject(map,"detail");//调拨申请详情信息
        Map<String,Object> header = VtuzxUtil.getObject(map,"header");//调拨申请单据头
        //生成调拨单
        Long detailId = VtuzxUtil.getLong(detail,"id");//调拨申请详情id
        StkTransferAppDetaill stkTransferAppDetaill = stkTransferAppDetailDao.selectById(detailId);

        StkTransfer stkTransfer = new StkTransfer();//调拨单单据头
        String billNo = IXqcConst.createBillNo(BillType.DBRK);
        stkTransfer.setFBillNo(billNo);
        stkTransfer.setCreateTime(new Date());
        stkTransfer.setFCREATEUSER(userName);

        StkTransferDetail stkTransferDetail = new StkTransferDetail();

        stkTransferDetail.setTEMP(false);
        stkTransferDetail.setFBILLNO(billNo);
        stkTransferDetail.setFDestStockId(stockNo);//调入仓库编码
        stkTransferDetail.setFDestStockLocId(locationNo);//调入仓位编码
        stkTransferDetail.setFMATERIALNUMBER(stkTransferAppDetaill.getFMATERIALNO());
        stkTransferDetail.setFMATERIALNAME(stkTransferAppDetaill.getFMATERIALNAME());
        stkTransferDetail.setFSPECIFICATION(stkTransferAppDetaill.getFSPECIFICATION());
        stkTransferDetail.setFUNITNAME(stkTransferAppDetaill.getFUNITNAME());
        stkTransferDetail.setFUNITID(stkTransferAppDetaill.getFUNITNO());
        stkTransferDetail.setFQTY(VtuzxUtil.getDouble(detail,"fqty"));//数量

        stkTransferDetail.setFSrcStockId(VtuzxUtil.getString(detail,"fstockno"));//调出仓库
        stkTransferDetail.setFSrcStockName(stkTransferAppDetaill.getFSTOCKNAME());
        stkTransferDetail.setFSrcStockLocName(VtuzxUtil.getString(detail,"flocationo"));
        stkTransferDetail.setFSrcStockLocId(VtuzxUtil.getString(detail,"flocationo"));//调出仓位
//        stkTransferDetail.setTRAYNO(trayNo);
        stkTransferDetail.setUSERID(user_id);
        stkTransferDetail.setTransferAppId(Math.toIntExact(detailId));
        List<StkTransferDetail> transferDetailList = new ArrayList<>();
        transferDetailList.add(stkTransferDetail);

        //调拨单传金蝶
        try {
            syncKingdeeOrderService.syncTransfer(user_id,stkTransfer,transferDetailList);
        } catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }
        boolean res = stkTransferService.save(stkTransfer);
        boolean detailRes = stkTransferDetailService.saveOrUpdateBatch(transferDetailList);

        return res;
    }
}
